package main

import (
	"log"
	"net/http"
	"time"

	"github.com/gin-gonic/gin"
	"golang.org/x/sync/errgroup"
)

// 处理属于同一总体任务的子任务的goroutine的集合
var (
	g errgroup.Group
)

func router02() http.Handler {
	e := gin.New()
	e.Use(gin.Recovery())
	e.GET("/", func(c *gin.Context) {
		c.JSON(
			http.StatusOK,
			gin.H{
				"code": http.StatusOK,
				"msg":  "Welcome server 02 blog.weiyigeek.top",
			},
		)
	})
	return e
}

func main() {
	// Default返回一个Engine实例，该实例已连接Logger和Recovery中间件。
	router := gin.Default()

	// 服务s1.用于运行HTTP服务器的参数 （常规参数）
	s1 := &http.Server{
		// Gin运行的监听端口
		Addr: ":8080",
		// 要调用的处理程序，http.DefaultServeMux如果为nil
		Handler: router,
		// ReadTimeout是读取整个请求（包括正文）的最长持续时间。
		ReadTimeout: 5 * time.Second,
		// WriteTimeout是超时写入响应之前的最长持续时间
		WriteTimeout: 10 * time.Second,
		// MaxHeaderBytes控制服务器解析请求标头的键和值（包括请求行）时读取的最大字节数 (通常情况下不进行设置)
		MaxHeaderBytes: 1 << 20,
	}

	// Go在一个新的goroutine中调用给定的函数,此处将Go语言的并发体现的淋漓尽致。
	g.Go(func() error {
		return s1.ListenAndServe()
	})

	// 配置Gin中间件
	// Recovery返回一个中间件，该中间件可以从任何恐慌中恢复，并在出现恐慌时写入500。
	router.Use(gin.Recovery())

	// 服务s1的路由
	router.GET("/", func(c *gin.Context) {
		c.JSON(
			http.StatusOK,
			gin.H{
				"code": http.StatusOK,
				"msg":  "Welcome server 01 www.weiyigeek.top",
			},
		)
	})

	// ============================================================================

	// gin服务2.定义了不同的监听端口以及Handler
	s2 := &http.Server{
		Addr:         ":8081",
		Handler:      router02(),
		ReadTimeout:  5 * time.Second,
		WriteTimeout: 10 * time.Second,
	}
	g.Go(func() error {
		return s2.ListenAndServe()
	})

	if err := g.Wait(); err != nil {
		log.Fatal(err)
	}
}
